## Reads in AOI position text files from Toii
## Will return tibble of columns sec, x, y, with rows for each timestamp/AOI position
get_xy_timestamp <- function(z){
x <- read_lines(z) %>%
  as_tibble() %>%
  rowid_to_column("ID")
# pull out timestamp rows
timestamps <- x %>%
  filter(str_detect(value, "timestamp")) %>%
  separate(value, into = c("throw","timestamp"), sep = " = ") %>%
  separate(timestamp, into = c("one","two","sec"), sep = ":") %>%
  select(sec) %>%
  mutate(sec = as.numeric(sec))
# Find AOI coordinate rows
xys <- x %>%
  mutate(find = str_detect(value, "X\tY"))
# first vertex (2 rows after each "XY" line)
xys_row <- which(xys$find) + 2
xy1 <- x %>%
  filter(ID %in% xys_row) %>%
  separate(value, into = c("x1","y1"), sep = "\t") %>%
  select(-ID)
# opposite vertex (2 more rows down)
xys_row <- xys_row + 2
xy2 <- x %>%
  filter(ID %in% xys_row) %>%
  separate(value, into = c("x2","y2"), sep = "\t") %>%
  select(-ID)
# Now get average XY position per timestamp
xys <- cbind(timestamps, xy1, xy2) %>%
  mutate_all(as.numeric) %>%
  rowwise() %>%
  mutate(x = mean(x1,x2),
         y = mean(y1, y2)) %>%
  select(sec, x, y)
}

Let’s give this a shot!!

Three Bears Forward

First let’s see who’s in our dataset. This is Test 1 - 3 Bears - Forward. We’re pulling cleaned-up names and assigned groups from our final dataset that we used in our AOI analysis. Then we are removing participants whose Three Bears Forward story wasn’t included in our AOI analysis due to <25% looking time or other reasons.

library(tidyverse)
library(openxlsx)
library(janitor)
# Get Three Bears data
data <- read.xlsx("Test1_Cindy_bears_FW_Examine for Spatial Referencing.xlsx") %>%
  clean_names() %>%
  rename(y = gaze_point_y_mc_spx,
         language = language_value,
         name = participant_name,
         group = group_value)
# Pull clean names and join to data (and add Laura2 for Laura (missing stories))
cleannames <- read_csv("partnames.csv") %>%
  distinct() %>%
  rename(name = participant) %>%
  filter(name != "Laura2")
data <- data %>% 
  left_join(cleannames, by = "name") %>%
  select(-name) %>%
  rename(name = new_participant) %>%
  filter(!is.na(name))
# Pull final group assignments and join to data
cleangroups <- read_csv("finaldataset.csv") %>%
  select(participant, maingroup) %>%
  rename(name = participant) %>%
  distinct()
data <- data %>% left_join(cleangroups, by = "name") %>%
  select(-group)
# Let's find out who was NOT included in Three Bears
excluded <- read_csv("finaldataset.csv") %>%
  select(participant, maingroup, story, direction, eye_exclude) %>%
  filter(story == "Goldilocks" & direction == "forward") %>%
  rename(name = participant) %>%
  select(name, eye_exclude)
data <- data %>% left_join(excluded, by = "name") %>%
  filter(!eye_exclude) %>%
  filter(!is.na(eye_exclude))
data %>% select(name, maingroup) %>% distinct()

Now let’s graph!!

Messy, I know, but already we can see some HearingNovice has big shifts downward. And some HearingLate too.

data %>%
  ggplot(aes(x = gaze_point_index, y = y, color = maingroup, group = name)) + geom_line() + 
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw()

Group Averages

Next, let’s make group averages.

averaged_y <- data %>%
  group_by(maingroup, gaze_point_index) %>%
  summarise(y_mean = mean(y, na.rm = T),
            y_sd = sd(y, na.rm = T),
            y_count = n(),
            y_se = y_sd/sqrt(y_count))
averaged_y %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw() +
  facet_wrap("maingroup")

averaged_y %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw()

Group Averages With Smoothing

So I’ll back up and smooth each person’s data using a moving average window of span = 5. Taken from our adult manuscript which had this:

The data were then smoothed with a standard moving average noise reduction algorithm (window size = 5 samples) which acts as a low-pass filter that reduces the influence of microsaccades, blinks, and large data gaps (based on Yarbus, 1967).

The below chart shows Adam’s data, blue is unsmoothed and red is smoothed.

data <- data %>%
  group_by(maingroup, recording_name) %>%
  mutate(y_ma = RcppRoll::roll_mean(y, n = 5, fill = 0))
data %>%
  filter(recording_name == "Adam_Good") %>%
  ggplot() +
  geom_line(aes(x = gaze_point_index, y = y), color = "blue", alpha = 0.25, size = 0.5) +
  geom_line(aes(x = gaze_point_index, y = y_ma), color = "red", size = 0.2) +
  scale_y_reverse(limits = c(475, 325)) +
  theme_bw()

So that’s nice. Let’s go do group averages again.

averaged_y <- data %>%
  group_by(maingroup, gaze_point_index) %>%
  summarise(y_mean = mean(y_ma, na.rm = T),
            y_sd = sd(y_ma, na.rm = T),
            y_count = n(),
            y_se = y_sd/sqrt(y_count))
averaged_y %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw() +
  facet_wrap("maingroup")

averaged_y %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw()

averaged_y %>%
  filter(maingroup == "DeafEarly" | maingroup == "HearingNovice") %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(700,300)) +
  theme_bw()

Group Averages With More Smoothing

Maybe we should smooth even more. Sample size = 10!

data <- data %>%
  group_by(maingroup, recording_name) %>%
  mutate(y_ma2 = RcppRoll::roll_mean(y, n = 10, fill = 0))
# data %>%
#   filter(recording_name == "Adam_Good") %>%
#   ggplot() +
#   geom_line(aes(x = gaze_point_index, y = y), color = "blue", alpha = 0.25, size = 0.5) +
#   geom_line(aes(x = gaze_point_index, y = y_ma2), color = "red", size = 0.2) +
#   scale_y_reverse(limits = c(475, 325)) +
#   theme_bw()
averaged_y <- data %>%
  group_by(maingroup, gaze_point_index) %>%
  summarise(y_mean = mean(y_ma2, na.rm = T),
            y_sd = sd(y_ma2, na.rm = T),
            y_count = n(),
            y_se = y_sd/sqrt(y_count))
averaged_y %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw() +
  facet_wrap("maingroup")

averaged_y %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw()

averaged_y %>%
  filter(maingroup == "DeafEarly" | maingroup == "HearingNovice") %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(700,300)) +
  theme_bw()

Everything Else That Was Already Here

Next let’s plot the moments where spatial referencing happens. Those are frames

  1. 198 to 223
  2. 265 to 288
  3. 352 to 380

The max gazepointindex is around 2580. At 120 Hz, that’s 21.5 seconds which is just right, that’s the length. Let’s go ahead and convert gazepointindex to seconds.

So we just have to convert frames to gazepointindex. The video is a total of 536 frames, at 25 FPS that’s 21.5 seconds. 535/25 = 21.5, so we divide all those frames by 25.

  1. 7.92s to 8.92s
  2. 10.6s to 11.52s
  3. 14.08s to 15.2s

And plot those!

data <- data %>%
  rowwise() %>%
  mutate(secs = gaze_point_index/120)
data %>%
  ggplot(aes(x = secs, y = y, color = maingroup, group = name)) + 
  scale_y_reverse() + 
  geom_line() + 
  annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  theme_bw()

Maybe easier if we separate groups of signers.

data %>%
  ggplot(aes(x = secs, y = y, color = maingroup, group = name)) + 
  scale_y_reverse() + 
  geom_line(alpha = 0.5) + 
  annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  facet_grid(maingroup ~ .) +
  theme_bw() +
  guides(color = FALSE)

Next, we’re going to add AOI position information. We’re going to pull in information on signers’ right hand position (and then apply the same idea to other body parts). I successfully wrote a function called get_xy_timestamp to do this! Yay. I’m chuffed, as the British would say.

Let’s try this on Stephanie’s data. Let’s see if we can find a correlation between any of those and the eye gaze y-position.

# We add one more row to the xy_timestamp data to align it with the end of the eye gaze data.
rhand <- get_xy_timestamp("aoi_position/Cindy_bears_FW_Position of Right Hand.txt") %>%
  add_row(sec = 21.5, x = 640.16, y = 1055.97)
lhand <- get_xy_timestamp("aoi_position/Cindy_bears_FW_Position of Left Hand.txt") %>%
  add_row(sec = 21.5, x = 703.74, y = 1058.39)
mouth <- get_xy_timestamp("aoi_position/Cindy_bears_FW_Position of mouth small.txt") %>%
  add_row(sec = 21.5, x = 656.37, y = 373.99)
# Get Stephanie's data
steph <- filter(data, name == "Stephanie")
steph %>%
  ggplot(aes(x = secs, y = y)) + 
  scale_y_reverse(limits = c(1200,0), expand = c(0,0)) + 
  geom_line(alpha = 1, color = "purple") + 
  # annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # geom_step(data = rhand, aes(x = sec, y = y), color = "red", linetype = "longdash", alpha = 0.5) + 
  # geom_step(data = lhand, aes(x = sec, y = y), color = "blue", linetype = "longdash", alpha = 0.5) + 
  # geom_step(data = mouth, aes(x = sec, y = y), color = "black", linetype = "longdash", alpha = 0.5) + 
  # annotate("text", label = "Right Hand", x = 3, y = 1000, color = "red", alpha = 0.5) +
  # annotate("text", label = "Left Hand", x = 3, y = 1100, color = "blue", alpha = 0.5) +
  # annotate("text", label = "Mouth", x = 3, y = 200, color = "black", alpha = 0.5) +
  ggtitle("Stephanie") +
  theme_bw() +
  theme(panel.grid.minor.y = element_blank())

steph %>%
  ggplot(aes(x = secs, y = y)) + 
  scale_y_reverse(limits = c(1200,0), expand = c(0,0)) + 
  geom_line(alpha = 1, color = "purple") + 
  # annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
#  geom_step(data = rhand, aes(x = sec, y = y), color = "red", linetype = "longdash", alpha = 0.5) + 
#  geom_step(data = lhand, aes(x = sec, y = y), color = "blue", linetype = "longdash", alpha = 0.5) + 
  geom_step(data = mouth, aes(x = sec, y = y), color = "black", linetype = "longdash", alpha = 0.5) + 
# annotate("text", label = "Right Hand", x = 3, y = 1000, color = "red", alpha = 0.5) +
#  annotate("text", label = "Left Hand", x = 3, y = 1100, color = "blue", alpha = 0.5) +
  annotate("text", label = "Mouth", x = 3, y = 250, color = "black", alpha = 0.5) +
  ggtitle("Stephanie") +
  theme_bw() +
  theme(panel.grid.minor.y = element_blank())

steph %>%
  ggplot(aes(x = secs, y = y)) + 
  scale_y_reverse(limits = c(1200,0), expand = c(0,0)) + 
  geom_line(alpha = 1, color = "purple") + 
  # annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  geom_step(data = rhand, aes(x = sec, y = y), color = "red", linetype = "longdash", alpha = 0.5) + 
#  geom_step(data = lhand, aes(x = sec, y = y), color = "blue", linetype = "longdash", alpha = 0.5) + 
  geom_step(data = mouth, aes(x = sec, y = y), color = "black", linetype = "longdash", alpha = 0.5) + 
  annotate("text", label = "Right Hand", x = 3, y = 1000, color = "red", alpha = 0.5) +
#  annotate("text", label = "Left Hand", x = 3, y = 1100, color = "blue", alpha = 0.5) +
  annotate("text", label = "Mouth", x = 3, y = 250, color = "black", alpha = 0.5) +
  ggtitle("Stephanie") +
  theme_bw() +
  theme(panel.grid.minor.y = element_blank())

steph %>%
  ggplot(aes(x = secs, y = y)) + 
  scale_y_reverse(limits = c(1200,0), expand = c(0,0)) + 
  geom_line(alpha = 1, color = "purple") + 
  # annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  geom_step(data = rhand, aes(x = sec, y = y), color = "red", linetype = "longdash", alpha = 0.5) + 
  geom_step(data = lhand, aes(x = sec, y = y), color = "blue", linetype = "longdash", alpha = 0.5) + 
  geom_step(data = mouth, aes(x = sec, y = y), color = "black", linetype = "longdash", alpha = 0.5) + 
  annotate("text", label = "Right Hand", x = 3, y = 1000, color = "red", alpha = 0.5) +
  annotate("text", label = "Left Hand", x = 3, y = 1100, color = "blue", alpha = 0.5) +
  annotate("text", label = "Mouth", x = 3, y = 250, color = "black", alpha = 0.5) +
  ggtitle("Stephanie") +
  theme_bw() +
  theme(panel.grid.minor.y = element_blank())

Now let’s work on correlations. First, our AOI vectors are not the same size as our eye gaze vectors, and the x/y position is irregularly spaced across time (irregularly spaced key frames).

# The following code will "expand" the rhand data vectors to fit the length of Stephanie's data vectors.
time_index <- steph$secs
closest <- function(x){
  which.min(abs(time_index-x))
}
index_loc <- map_int(rhand$sec, closest)
rhand <- cbind(rhand, time_index[index_loc]) %>%
  select(-sec) %>%
  rename(sec = "time_index[index_loc]") %>%
  select(sec, x, y)
rhand_full <- select(steph, secs) %>%
  rename(sec = secs) %>%
  left_join(rhand) %>%
  fill(x) %>%
  fill(y) %>%
  slice(1:(nrow(.)-1))
Joining, by = "sec"
rhand_full <- rhand_full %>%
  filter(sec < rhand$sec[172]) %>%
  filter(sec >= rhand$sec[2])
steph <- steph %>%
  filter(secs < rhand$sec[172]) %>%
  filter(secs >= rhand$sec[2])
a <- rhand_full$y
a <- a[1:length(a)-1] # Shorten it by one element
b <- steph$y
# Then run correlations
cor(a,b, use = "complete.obs") # basic correlation
[1] 0.2894728
that <- ccf(a,b, lag.max = 400, type = "correlation", na.action = na.pass, plot = T) # auto-correlation

Let’s separate out individual signers.

make_signer_plots <- function(groupname, line_color) {
  data %>%
  filter(maingroup == groupname) %>%
  ggplot(aes(x = secs, y = y)) + 
  scale_y_reverse() + 
  geom_line(alpha = 1, color = line_color) + 
  annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  geom_step(data = rhand, aes(x = sec, y = y), color = "red", linetype = "longdash", alpha = 0.5) + 
  geom_step(data = lhand, aes(x = sec, y = y), color = "blue", linetype = "longdash", alpha = 0.5) + 
  geom_step(data = mouth, aes(x = sec, y = y), color = "black", linetype = "longdash", alpha = 0.5) + 
  annotate("text", label = "Right Hand", x = 3, y = 1000, color = "red", alpha = 0.5) +
  annotate("text", label = "Left Hand", x = 3, y = 1100, color = "blue", alpha = 0.5) +
  annotate("text", label = "Mouth", x = 3, y = 200, color = "black", alpha = 0.5) +
  facet_grid(name ~ .) +
  ggtitle(groupname) +
  theme_bw()
}
make_signer_plots("DeafEarly", "red")

make_signer_plots("DeafLate", "dark green")

make_signer_plots("HearingLate", "blue")

make_signer_plots("HearingNovice", "purple")

Okay so with Early ASL obviously very steady gaze. NoviceASL has lot of downshifts. Some align with spatial referencing, some do not. We need more of them (let’s look at other stories w better data).

Midas Forward

# Get Midas data
data <- read_csv("../Adult Data/rawdata/midasfw.csv") %>%
  clean_names() %>%
  rename(y = gaze_point_y_mc_spx,
         language = language_value,
         name = participant_name,
         group = group_value)
# Pull clean names and join to data
cleannames <- read_csv("partnames.csv") %>%
  distinct() %>%
  rename(name = participant)
data <- data %>% left_join(cleannames, by = "name") %>%
  select(-name) %>%
  rename(name = new_participant) %>%
  filter(!is.na(name))
# Pull final group assignments and join to data
cleangroups <- read_csv("finaldataset.csv") %>%
  select(participant, maingroup) %>%
  rename(name = participant) %>%
  distinct()
data <- data %>% left_join(cleangroups, by = "name") %>%
  select(-group)
# Let's find out who was NOT included in Three Bears
excluded <- read_csv("finaldataset.csv") %>%
  select(participant, maingroup, story, direction, eye_exclude) %>%
  filter(story == "KingMidas" & direction == "forward") %>%
  rename(name = participant) %>%
  select(name, eye_exclude)
data <- data %>% left_join(excluded, by = "name") %>%
  filter(!eye_exclude) %>%
  filter(!is.na(eye_exclude))
data %>% select(name, maingroup) %>% distinct()

Now let’s graph!!

Hm. One person seems wrong.

data %>%
  ggplot(aes(x = gaze_point_index, y = y, color = maingroup, group = name)) + geom_line() + scale_y_reverse()

Okay it’s Jesse’s data that seems off. We’ll remove him for now and come back to it, figure out why.

data %>% filter(gaze_point_index > 30000) %>% select(name) %>% distinct() %>% head()
data <- data %>%
  filter(name != "Jesse")
data %>%
  ggplot(aes(x = gaze_point_index, y = y, color = maingroup, group = name)) + geom_line() + 
  scale_y_reverse() +
  scale_x_continuous(limits = c(0,4500))

Next let’s plot the moments where spatial referencing happens. Those are frames

  1. 248 to 427
  2. 460 to 508
  3. 512 to 560

Like before, we’ll convert gazepointindex to seconds (by dividing 120) and all frames to seconds (by dividing 25).

  1. 9.92s to 17.08s
  2. 18.4s to 20.32s
  3. 20.48s to 22.4s
data <- data %>%
  rowwise() %>%
  mutate(secs = gaze_point_index/120)
data %>%
  ggplot(aes(x = secs, y = y, color = maingroup, group = name)) + 
  scale_y_reverse() + 
  scale_x_continuous(limits = c(0, 37.5)) +
  geom_line() + 
  annotate("rect", xmin = 9.92, xmax = 17.08, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 18.4, xmax = 20.32, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 20.48, xmax = 22.4, ymin = 0, ymax = 900,
  alpha = .2, fill = "red")

Maybe easier if we separate groups of signers.

data %>%
  ggplot(aes(x = secs, y = y, color = maingroup, group = name)) + 
  scale_y_reverse() + 
  scale_x_continuous(limits = c(0, 37.5)) +
  geom_line(alpha = 0.5) + 
  annotate("rect", xmin = 9.92, xmax = 17.08, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 18.4, xmax = 20.32, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 20.48, xmax = 22.4, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  facet_grid(maingroup ~ .)

Individual signers.

data %>%
  filter(maingroup == "DeafEarly") %>%
  ggplot(aes(x = secs, y = y, group = name)) + 
  scale_x_continuous(limits = c(0, 37.5)) +
  scale_y_reverse() + 
  geom_line(alpha = 1, color = "red") + 
  annotate("rect", xmin = 9.92, xmax = 17.08, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 18.4, xmax = 20.32, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 20.48, xmax = 22.4, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  facet_grid(name ~ .) +
  ggtitle("DeafEarly")

data %>%
  filter(maingroup == "DeafLate") %>%
  ggplot(aes(x = secs, y = y, group = name)) + 
  scale_y_reverse() + 
  scale_x_continuous(limits = c(0, 37.5)) +
  geom_line(alpha = 1, color = "dark green") + 
  annotate("rect", xmin = 9.92, xmax = 17.08, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 18.4, xmax = 20.32, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 20.48, xmax = 22.4, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  facet_grid(name ~ .) +
  ggtitle("DeafLate")

data %>%
  filter(maingroup == "HearingLate") %>%
  ggplot(aes(x = secs, y = y, group = name)) + 
  scale_y_reverse() + 
  scale_x_continuous(limits = c(0, 37.5)) +
  geom_line(alpha = 1, color = "blue") + 
  annotate("rect", xmin = 9.92, xmax = 17.08, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 18.4, xmax = 20.32, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 20.48, xmax = 22.4, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  facet_grid(name ~ .) +
  ggtitle("HearingLate")

data %>%
  filter(maingroup == "HearingNovice") %>%
  ggplot(aes(x = secs, y = y, group = name)) + 
  scale_y_reverse() + 
  scale_x_continuous(limits = c(0, 37.5)) +
  geom_line(alpha = 1, color = "purple") + 
  annotate("rect", xmin = 9.92, xmax = 17.08, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 18.4, xmax = 20.32, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 20.48, xmax = 22.4, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  facet_grid(name ~ .) +
  ggtitle("HearingNovice")

LS0tCnRpdGxlOiAiU3BhdGlhbCBSZWZlcmVuY2luZyIKYXV0aG9yOiAiQWRhbSBTdG9uZSwgUGhEIgpkYXRlOiAnYHIgZm9ybWF0KFN5cy5EYXRlKCksICIlbS0lZC0lWSIpYCcKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIHRoZW1lOiBwYXBlcgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCgpgYGB7cn0KIyMgUmVhZHMgaW4gQU9JIHBvc2l0aW9uIHRleHQgZmlsZXMgZnJvbSBUb2lpCiMjIFdpbGwgcmV0dXJuIHRpYmJsZSBvZiBjb2x1bW5zIHNlYywgeCwgeSwgd2l0aCByb3dzIGZvciBlYWNoIHRpbWVzdGFtcC9BT0kgcG9zaXRpb24KCmdldF94eV90aW1lc3RhbXAgPC0gZnVuY3Rpb24oeil7Cgp4IDwtIHJlYWRfbGluZXMoeikgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcm93aWRfdG9fY29sdW1uKCJJRCIpCgojIHB1bGwgb3V0IHRpbWVzdGFtcCByb3dzCnRpbWVzdGFtcHMgPC0geCAlPiUKICBmaWx0ZXIoc3RyX2RldGVjdCh2YWx1ZSwgInRpbWVzdGFtcCIpKSAlPiUKICBzZXBhcmF0ZSh2YWx1ZSwgaW50byA9IGMoInRocm93IiwidGltZXN0YW1wIiksIHNlcCA9ICIgPSAiKSAlPiUKICBzZXBhcmF0ZSh0aW1lc3RhbXAsIGludG8gPSBjKCJvbmUiLCJ0d28iLCJzZWMiKSwgc2VwID0gIjoiKSAlPiUKICBzZWxlY3Qoc2VjKSAlPiUKICBtdXRhdGUoc2VjID0gYXMubnVtZXJpYyhzZWMpKQoKIyBGaW5kIEFPSSBjb29yZGluYXRlIHJvd3MKeHlzIDwtIHggJT4lCiAgbXV0YXRlKGZpbmQgPSBzdHJfZGV0ZWN0KHZhbHVlLCAiWFx0WSIpKQoKIyBmaXJzdCB2ZXJ0ZXggKDIgcm93cyBhZnRlciBlYWNoICJYWSIgbGluZSkKeHlzX3JvdyA8LSB3aGljaCh4eXMkZmluZCkgKyAyCgp4eTEgPC0geCAlPiUKICBmaWx0ZXIoSUQgJWluJSB4eXNfcm93KSAlPiUKICBzZXBhcmF0ZSh2YWx1ZSwgaW50byA9IGMoIngxIiwieTEiKSwgc2VwID0gIlx0IikgJT4lCiAgc2VsZWN0KC1JRCkKCiMgb3Bwb3NpdGUgdmVydGV4ICgyIG1vcmUgcm93cyBkb3duKQp4eXNfcm93IDwtIHh5c19yb3cgKyAyCgp4eTIgPC0geCAlPiUKICBmaWx0ZXIoSUQgJWluJSB4eXNfcm93KSAlPiUKICBzZXBhcmF0ZSh2YWx1ZSwgaW50byA9IGMoIngyIiwieTIiKSwgc2VwID0gIlx0IikgJT4lCiAgc2VsZWN0KC1JRCkKCiMgTm93IGdldCBhdmVyYWdlIFhZIHBvc2l0aW9uIHBlciB0aW1lc3RhbXAKeHlzIDwtIGNiaW5kKHRpbWVzdGFtcHMsIHh5MSwgeHkyKSAlPiUKICBtdXRhdGVfYWxsKGFzLm51bWVyaWMpICU+JQogIHJvd3dpc2UoKSAlPiUKICBtdXRhdGUoeCA9IG1lYW4oeDEseDIpLAogICAgICAgICB5ID0gbWVhbih5MSwgeTIpKSAlPiUKICBzZWxlY3Qoc2VjLCB4LCB5KQp9CmBgYAoKTGV0J3MgZ2l2ZSB0aGlzIGEgc2hvdCEhCgojIFRocmVlIEJlYXJzIEZvcndhcmQgCkZpcnN0IGxldCdzIHNlZSB3aG8ncyBpbiBvdXIgZGF0YXNldC4gVGhpcyBpcyBUZXN0IDEgLSAzIEJlYXJzIC0gRm9yd2FyZC4gV2UncmUgcHVsbGluZyBjbGVhbmVkLXVwIG5hbWVzIGFuZCBhc3NpZ25lZCBncm91cHMgZnJvbSBvdXIgZmluYWwgZGF0YXNldCB0aGF0IHdlIHVzZWQgaW4gb3VyIEFPSSBhbmFseXNpcy4gVGhlbiB3ZSBhcmUgcmVtb3ZpbmcgcGFydGljaXBhbnRzIHdob3NlIFRocmVlIEJlYXJzIEZvcndhcmQgc3Rvcnkgd2Fzbid0IGluY2x1ZGVkIGluIG91ciBBT0kgYW5hbHlzaXMgZHVlIHRvIDwyNSUgbG9va2luZyB0aW1lIG9yIG90aGVyIHJlYXNvbnMuIAoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkob3Blbnhsc3gpCmxpYnJhcnkoamFuaXRvcikKCiMgR2V0IFRocmVlIEJlYXJzIGRhdGEKZGF0YSA8LSByZWFkLnhsc3goIlRlc3QxX0NpbmR5X2JlYXJzX0ZXX0V4YW1pbmUgZm9yIFNwYXRpYWwgUmVmZXJlbmNpbmcueGxzeCIpICU+JQogIGNsZWFuX25hbWVzKCkgJT4lCiAgcmVuYW1lKHkgPSBnYXplX3BvaW50X3lfbWNfc3B4LAogICAgICAgICBsYW5ndWFnZSA9IGxhbmd1YWdlX3ZhbHVlLAogICAgICAgICBuYW1lID0gcGFydGljaXBhbnRfbmFtZSwKICAgICAgICAgZ3JvdXAgPSBncm91cF92YWx1ZSkKCiMgUHVsbCBjbGVhbiBuYW1lcyBhbmQgam9pbiB0byBkYXRhIChhbmQgYWRkIExhdXJhMiBmb3IgTGF1cmEgKG1pc3Npbmcgc3RvcmllcykpCmNsZWFubmFtZXMgPC0gcmVhZF9jc3YoInBhcnRuYW1lcy5jc3YiKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIHJlbmFtZShuYW1lID0gcGFydGljaXBhbnQpICU+JQogIGZpbHRlcihuYW1lICE9ICJMYXVyYTIiKQoKZGF0YSA8LSBkYXRhICU+JSAKICBsZWZ0X2pvaW4oY2xlYW5uYW1lcywgYnkgPSAibmFtZSIpICU+JQogIHNlbGVjdCgtbmFtZSkgJT4lCiAgcmVuYW1lKG5hbWUgPSBuZXdfcGFydGljaXBhbnQpICU+JQogIGZpbHRlcighaXMubmEobmFtZSkpCgojIFB1bGwgZmluYWwgZ3JvdXAgYXNzaWdubWVudHMgYW5kIGpvaW4gdG8gZGF0YQpjbGVhbmdyb3VwcyA8LSByZWFkX2NzdigiZmluYWxkYXRhc2V0LmNzdiIpICU+JQogIHNlbGVjdChwYXJ0aWNpcGFudCwgbWFpbmdyb3VwKSAlPiUKICByZW5hbWUobmFtZSA9IHBhcnRpY2lwYW50KSAlPiUKICBkaXN0aW5jdCgpCgpkYXRhIDwtIGRhdGEgJT4lIGxlZnRfam9pbihjbGVhbmdyb3VwcywgYnkgPSAibmFtZSIpICU+JQogIHNlbGVjdCgtZ3JvdXApCgojIExldCdzIGZpbmQgb3V0IHdobyB3YXMgTk9UIGluY2x1ZGVkIGluIFRocmVlIEJlYXJzCmV4Y2x1ZGVkIDwtIHJlYWRfY3N2KCJmaW5hbGRhdGFzZXQuY3N2IikgJT4lCiAgc2VsZWN0KHBhcnRpY2lwYW50LCBtYWluZ3JvdXAsIHN0b3J5LCBkaXJlY3Rpb24sIGV5ZV9leGNsdWRlKSAlPiUKICBmaWx0ZXIoc3RvcnkgPT0gIkdvbGRpbG9ja3MiICYgZGlyZWN0aW9uID09ICJmb3J3YXJkIikgJT4lCiAgcmVuYW1lKG5hbWUgPSBwYXJ0aWNpcGFudCkgJT4lCiAgc2VsZWN0KG5hbWUsIGV5ZV9leGNsdWRlKQoKZGF0YSA8LSBkYXRhICU+JSBsZWZ0X2pvaW4oZXhjbHVkZWQsIGJ5ID0gIm5hbWUiKSAlPiUKICBmaWx0ZXIoIWV5ZV9leGNsdWRlKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGV5ZV9leGNsdWRlKSkKCmRhdGEgJT4lIHNlbGVjdChuYW1lLCBtYWluZ3JvdXApICU+JSBkaXN0aW5jdCgpCmBgYAoKTm93IGxldCdzIGdyYXBoISEgCgpNZXNzeSwgSSBrbm93LCBidXQgYWxyZWFkeSB3ZSBjYW4gc2VlIHNvbWUgSGVhcmluZ05vdmljZSBoYXMgYmlnIHNoaWZ0cyBkb3dud2FyZC4gQW5kIHNvbWUgSGVhcmluZ0xhdGUgdG9vLgoKYGBge3J9CmRhdGEgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgeSA9IHksIGNvbG9yID0gbWFpbmdyb3VwLCBncm91cCA9IG5hbWUpKSArIGdlb21fbGluZSgpICsgCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSkgKwogIHRoZW1lX2J3KCkKYGBgCgojIEdyb3VwIEF2ZXJhZ2VzCgpOZXh0LCBsZXQncyBtYWtlIGdyb3VwIGF2ZXJhZ2VzLiAKCmBgYHtyfQphdmVyYWdlZF95IDwtIGRhdGEgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBnYXplX3BvaW50X2luZGV4KSAlPiUKICBzdW1tYXJpc2UoeV9tZWFuID0gbWVhbih5LCBuYS5ybSA9IFQpLAogICAgICAgICAgICB5X3NkID0gc2QoeSwgbmEucm0gPSBUKSwKICAgICAgICAgICAgeV9jb3VudCA9IG4oKSwKICAgICAgICAgICAgeV9zZSA9IHlfc2Qvc3FydCh5X2NvdW50KSkKCmF2ZXJhZ2VkX3kgJT4lCiAgZ2dwbG90KCkgKyAKICBnZW9tX2xpbmUoYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCB5ID0geV9tZWFuLCBjb2xvciA9IG1haW5ncm91cCkpICsKICBnZW9tX3JpYmJvbihhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIAogICAgICAgICAgICAgICAgICB5bWluID0geV9tZWFuLXlfc2UsIAogICAgICAgICAgICAgICAgICB5bWF4ID0geV9tZWFuK3lfc2UsCiAgICAgICAgICAgICAgICAgIGZpbGwgPSBtYWluZ3JvdXApLCBhbHBoYSA9IDAuNSkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEyMDAsMCkpICsKICB0aGVtZV9idygpICsKICBmYWNldF93cmFwKCJtYWluZ3JvdXAiKQoKYXZlcmFnZWRfeSAlPiUKICBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIHkgPSB5X21lYW4sIGNvbG9yID0gbWFpbmdyb3VwKSkgKwogIGdlb21fcmliYm9uKGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgCiAgICAgICAgICAgICAgICAgIHltaW4gPSB5X21lYW4teV9zZSwgCiAgICAgICAgICAgICAgICAgIHltYXggPSB5X21lYW4reV9zZSwKICAgICAgICAgICAgICAgICAgZmlsbCA9IG1haW5ncm91cCksIGFscGhhID0gMC41KSArCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSkgKwogIHRoZW1lX2J3KCkKYGBgCgojIEdyb3VwIEF2ZXJhZ2VzIFdpdGggU21vb3RoaW5nCgpTbyBJJ2xsIGJhY2sgdXAgYW5kIHNtb290aCBlYWNoIHBlcnNvbidzIGRhdGEgdXNpbmcgYSBtb3ZpbmcgYXZlcmFnZSB3aW5kb3cgb2Ygc3BhbiA9IDUuIFRha2VuIGZyb20gb3VyIGFkdWx0IG1hbnVzY3JpcHQgd2hpY2ggaGFkIHRoaXM6IAoKPiBUaGUgZGF0YSB3ZXJlIHRoZW4gc21vb3RoZWQgd2l0aCBhIHN0YW5kYXJkIG1vdmluZyBhdmVyYWdlIG5vaXNlIHJlZHVjdGlvbiBhbGdvcml0aG0gKHdpbmRvdyBzaXplID0gNSBzYW1wbGVzKSB3aGljaCBhY3RzIGFzIGEgbG93LXBhc3MgZmlsdGVyIHRoYXQgcmVkdWNlcyB0aGUgaW5mbHVlbmNlIG9mIG1pY3Jvc2FjY2FkZXMsIGJsaW5rcywgYW5kIGxhcmdlIGRhdGEgZ2FwcyAoYmFzZWQgb24gWWFyYnVzLCAxOTY3KS4gCgpUaGUgYmVsb3cgY2hhcnQgc2hvd3MgQWRhbSdzIGRhdGEsIGJsdWUgaXMgdW5zbW9vdGhlZCBhbmQgcmVkIGlzIHNtb290aGVkLiAKCgpgYGB7cn0KZGF0YSA8LSBkYXRhICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgcmVjb3JkaW5nX25hbWUpICU+JQogIG11dGF0ZSh5X21hID0gUmNwcFJvbGw6OnJvbGxfbWVhbih5LCBuID0gNSwgZmlsbCA9IDApKQoKZGF0YSAlPiUKICBmaWx0ZXIocmVjb3JkaW5nX25hbWUgPT0gIkFkYW1fR29vZCIpICU+JQogIGdncGxvdCgpICsKICBnZW9tX2xpbmUoYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCB5ID0geSksIGNvbG9yID0gImJsdWUiLCBhbHBoYSA9IDAuMjUsIHNpemUgPSAwLjUpICsKICBnZW9tX2xpbmUoYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCB5ID0geV9tYSksIGNvbG9yID0gInJlZCIsIHNpemUgPSAwLjIpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYyg0NzUsIDMyNSkpICsKICB0aGVtZV9idygpCmBgYAoKU28gdGhhdCdzIG5pY2UuIExldCdzIGdvIGRvIGdyb3VwIGF2ZXJhZ2VzIGFnYWluLiAKCmBgYHtyfQphdmVyYWdlZF95IDwtIGRhdGEgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBnYXplX3BvaW50X2luZGV4KSAlPiUKICBzdW1tYXJpc2UoeV9tZWFuID0gbWVhbih5X21hLCBuYS5ybSA9IFQpLAogICAgICAgICAgICB5X3NkID0gc2QoeV9tYSwgbmEucm0gPSBUKSwKICAgICAgICAgICAgeV9jb3VudCA9IG4oKSwKICAgICAgICAgICAgeV9zZSA9IHlfc2Qvc3FydCh5X2NvdW50KSkKCmF2ZXJhZ2VkX3kgJT4lCiAgZ2dwbG90KCkgKyAKICBnZW9tX2xpbmUoYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCB5ID0geV9tZWFuLCBjb2xvciA9IG1haW5ncm91cCkpICsKICBnZW9tX3JpYmJvbihhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIAogICAgICAgICAgICAgICAgICB5bWluID0geV9tZWFuLXlfc2UsIAogICAgICAgICAgICAgICAgICB5bWF4ID0geV9tZWFuK3lfc2UsCiAgICAgICAgICAgICAgICAgIGZpbGwgPSBtYWluZ3JvdXApLCBhbHBoYSA9IDAuNSkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEyMDAsMCkpICsKICB0aGVtZV9idygpICsKICBmYWNldF93cmFwKCJtYWluZ3JvdXAiKQoKYXZlcmFnZWRfeSAlPiUKICBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIHkgPSB5X21lYW4sIGNvbG9yID0gbWFpbmdyb3VwKSkgKwogIGdlb21fcmliYm9uKGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgCiAgICAgICAgICAgICAgICAgIHltaW4gPSB5X21lYW4teV9zZSwgCiAgICAgICAgICAgICAgICAgIHltYXggPSB5X21lYW4reV9zZSwKICAgICAgICAgICAgICAgICAgZmlsbCA9IG1haW5ncm91cCksIGFscGhhID0gMC41KSArCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSkgKwogIHRoZW1lX2J3KCkKCmF2ZXJhZ2VkX3kgJT4lCiAgZmlsdGVyKG1haW5ncm91cCA9PSAiRGVhZkVhcmx5IiB8IG1haW5ncm91cCA9PSAiSGVhcmluZ05vdmljZSIpICU+JQogIGdncGxvdCgpICsgCiAgZ2VvbV9saW5lKGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgeSA9IHlfbWVhbiwgY29sb3IgPSBtYWluZ3JvdXApKSArCiAgZ2VvbV9yaWJib24oYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCAKICAgICAgICAgICAgICAgICAgeW1pbiA9IHlfbWVhbi15X3NlLCAKICAgICAgICAgICAgICAgICAgeW1heCA9IHlfbWVhbit5X3NlLAogICAgICAgICAgICAgICAgICBmaWxsID0gbWFpbmdyb3VwKSwgYWxwaGEgPSAwLjUpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYyg3MDAsMzAwKSkgKwogIHRoZW1lX2J3KCkKYGBgCgojIEdyb3VwIEF2ZXJhZ2VzIFdpdGggTW9yZSBTbW9vdGhpbmcKCk1heWJlIHdlIHNob3VsZCBzbW9vdGggZXZlbiBtb3JlLiBTYW1wbGUgc2l6ZSA9IDEwISAKCmBgYHtyfQpkYXRhIDwtIGRhdGEgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCByZWNvcmRpbmdfbmFtZSkgJT4lCiAgbXV0YXRlKHlfbWEyID0gUmNwcFJvbGw6OnJvbGxfbWVhbih5LCBuID0gMTAsIGZpbGwgPSAwKSkKCiMgZGF0YSAlPiUKIyAgIGZpbHRlcihyZWNvcmRpbmdfbmFtZSA9PSAiQWRhbV9Hb29kIikgJT4lCiMgICBnZ3Bsb3QoKSArCiMgICBnZW9tX2xpbmUoYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCB5ID0geSksIGNvbG9yID0gImJsdWUiLCBhbHBoYSA9IDAuMjUsIHNpemUgPSAwLjUpICsKIyAgIGdlb21fbGluZShhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIHkgPSB5X21hMiksIGNvbG9yID0gInJlZCIsIHNpemUgPSAwLjIpICsKIyAgIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDQ3NSwgMzI1KSkgKwojICAgdGhlbWVfYncoKQoKYXZlcmFnZWRfeSA8LSBkYXRhICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgZ2F6ZV9wb2ludF9pbmRleCkgJT4lCiAgc3VtbWFyaXNlKHlfbWVhbiA9IG1lYW4oeV9tYTIsIG5hLnJtID0gVCksCiAgICAgICAgICAgIHlfc2QgPSBzZCh5X21hMiwgbmEucm0gPSBUKSwKICAgICAgICAgICAgeV9jb3VudCA9IG4oKSwKICAgICAgICAgICAgeV9zZSA9IHlfc2Qvc3FydCh5X2NvdW50KSkKCmF2ZXJhZ2VkX3kgJT4lCiAgZ2dwbG90KCkgKyAKICBnZW9tX2xpbmUoYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCB5ID0geV9tZWFuLCBjb2xvciA9IG1haW5ncm91cCkpICsKICBnZW9tX3JpYmJvbihhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIAogICAgICAgICAgICAgICAgICB5bWluID0geV9tZWFuLXlfc2UsIAogICAgICAgICAgICAgICAgICB5bWF4ID0geV9tZWFuK3lfc2UsCiAgICAgICAgICAgICAgICAgIGZpbGwgPSBtYWluZ3JvdXApLCBhbHBoYSA9IDAuNSkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEyMDAsMCkpICsKICB0aGVtZV9idygpICsKICBmYWNldF93cmFwKCJtYWluZ3JvdXAiKQoKYXZlcmFnZWRfeSAlPiUKICBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIHkgPSB5X21lYW4sIGNvbG9yID0gbWFpbmdyb3VwKSkgKwogIGdlb21fcmliYm9uKGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgCiAgICAgICAgICAgICAgICAgIHltaW4gPSB5X21lYW4teV9zZSwgCiAgICAgICAgICAgICAgICAgIHltYXggPSB5X21lYW4reV9zZSwKICAgICAgICAgICAgICAgICAgZmlsbCA9IG1haW5ncm91cCksIGFscGhhID0gMC41KSArCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSkgKwogIHRoZW1lX2J3KCkKCmF2ZXJhZ2VkX3kgJT4lCiAgZmlsdGVyKG1haW5ncm91cCA9PSAiRGVhZkVhcmx5IiB8IG1haW5ncm91cCA9PSAiSGVhcmluZ05vdmljZSIpICU+JQogIGdncGxvdCgpICsgCiAgZ2VvbV9saW5lKGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgeSA9IHlfbWVhbiwgY29sb3IgPSBtYWluZ3JvdXApKSArCiAgZ2VvbV9yaWJib24oYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCAKICAgICAgICAgICAgICAgICAgeW1pbiA9IHlfbWVhbi15X3NlLCAKICAgICAgICAgICAgICAgICAgeW1heCA9IHlfbWVhbit5X3NlLAogICAgICAgICAgICAgICAgICBmaWxsID0gbWFpbmdyb3VwKSwgYWxwaGEgPSAwLjUpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYyg3MDAsMzAwKSkgKwogIHRoZW1lX2J3KCkKYGBgCgojIEV2ZXJ5dGhpbmcgRWxzZSBUaGF0IFdhcyBBbHJlYWR5IEhlcmUKCk5leHQgbGV0J3MgcGxvdCB0aGUgbW9tZW50cyB3aGVyZSBzcGF0aWFsIHJlZmVyZW5jaW5nIGhhcHBlbnMuIFRob3NlIGFyZSBmcmFtZXMKCjEuIDE5OCB0byAyMjMKMS4gMjY1IHRvIDI4OAoxLiAzNTIgdG8gMzgwCgpUaGUgbWF4IGdhemVwb2ludGluZGV4IGlzIGFyb3VuZCAyNTgwLiBBdCAxMjAgSHosIHRoYXQncyAyMS41IHNlY29uZHMgd2hpY2ggaXMganVzdCByaWdodCwgdGhhdCdzIHRoZSBsZW5ndGguIExldCdzIGdvIGFoZWFkIGFuZCBjb252ZXJ0IGdhemVwb2ludGluZGV4IHRvIHNlY29uZHMuICAKClNvIHdlIGp1c3QgaGF2ZSB0byBjb252ZXJ0IGZyYW1lcyB0byBnYXplcG9pbnRpbmRleC4gVGhlIHZpZGVvIGlzIGEgdG90YWwgb2YgNTM2IGZyYW1lcywgYXQgMjUgRlBTIHRoYXQncyAyMS41IHNlY29uZHMuIDUzNS8yNSA9IDIxLjUsIHNvIHdlIGRpdmlkZSBhbGwgdGhvc2UgZnJhbWVzIGJ5IDI1LiAKCjEuIDcuOTJzIHRvIDguOTJzCjEuIDEwLjZzIHRvIDExLjUycwoxLiAxNC4wOHMgdG8gMTUuMnMgCgpBbmQgcGxvdCB0aG9zZSEKCmBgYHtyfQpkYXRhIDwtIGRhdGEgJT4lCiAgcm93d2lzZSgpICU+JQogIG11dGF0ZShzZWNzID0gZ2F6ZV9wb2ludF9pbmRleC8xMjApCgpkYXRhICU+JQogIGdncGxvdChhZXMoeCA9IHNlY3MsIHkgPSB5LCBjb2xvciA9IG1haW5ncm91cCwgZ3JvdXAgPSBuYW1lKSkgKyAKICBzY2FsZV95X3JldmVyc2UoKSArIAogIGdlb21fbGluZSgpICsgCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gNy45MiwgeG1heCA9IDguOTIsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDEwLjYsIHhtYXggPSAxMS41MiwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTQuMDgsIHhtYXggPSAxNS4yLCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICB0aGVtZV9idygpCmBgYAoKTWF5YmUgZWFzaWVyIGlmIHdlIHNlcGFyYXRlIGdyb3VwcyBvZiBzaWduZXJzLiAKCmBgYHtyfQpkYXRhICU+JQogIGdncGxvdChhZXMoeCA9IHNlY3MsIHkgPSB5LCBjb2xvciA9IG1haW5ncm91cCwgZ3JvdXAgPSBuYW1lKSkgKyAKICBzY2FsZV95X3JldmVyc2UoKSArIAogIGdlb21fbGluZShhbHBoYSA9IDAuNSkgKyAKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSA3LjkyLCB4bWF4ID0gOC45MiwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTAuNiwgeG1heCA9IDExLjUyLCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxNC4wOCwgeG1heCA9IDE1LjIsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGZhY2V0X2dyaWQobWFpbmdyb3VwIH4gLikgKwogIHRoZW1lX2J3KCkgKwogIGd1aWRlcyhjb2xvciA9IEZBTFNFKQpgYGAKCk5leHQsIHdlJ3JlIGdvaW5nIHRvIGFkZCBBT0kgcG9zaXRpb24gaW5mb3JtYXRpb24uIFdlJ3JlIGdvaW5nIHRvIHB1bGwgaW4gaW5mb3JtYXRpb24gb24gc2lnbmVycycgcmlnaHQgaGFuZCBwb3NpdGlvbiAoYW5kIHRoZW4gYXBwbHkgdGhlIHNhbWUgaWRlYSB0byBvdGhlciBib2R5IHBhcnRzKS4gSSBzdWNjZXNzZnVsbHkgd3JvdGUgYSBmdW5jdGlvbiBjYWxsZWQgYGdldF94eV90aW1lc3RhbXBgIHRvIGRvIHRoaXMhIFlheS4gSSdtIGNodWZmZWQsIGFzIHRoZSBCcml0aXNoIHdvdWxkIHNheS4KCkxldCdzIHRyeSB0aGlzIG9uIFN0ZXBoYW5pZSdzIGRhdGEuIExldCdzIHNlZSBpZiB3ZSBjYW4gZmluZCBhIGNvcnJlbGF0aW9uIGJldHdlZW4gYW55IG9mIHRob3NlIGFuZCB0aGUgZXllIGdhemUgeS1wb3NpdGlvbi4gCgpgYGB7cn0KCiMgV2UgYWRkIG9uZSBtb3JlIHJvdyB0byB0aGUgeHlfdGltZXN0YW1wIGRhdGEgdG8gYWxpZ24gaXQgd2l0aCB0aGUgZW5kIG9mIHRoZSBleWUgZ2F6ZSBkYXRhLgpyaGFuZCA8LSBnZXRfeHlfdGltZXN0YW1wKCJhb2lfcG9zaXRpb24vQ2luZHlfYmVhcnNfRldfUG9zaXRpb24gb2YgUmlnaHQgSGFuZC50eHQiKSAlPiUKICBhZGRfcm93KHNlYyA9IDIxLjUsIHggPSA2NDAuMTYsIHkgPSAxMDU1Ljk3KQpsaGFuZCA8LSBnZXRfeHlfdGltZXN0YW1wKCJhb2lfcG9zaXRpb24vQ2luZHlfYmVhcnNfRldfUG9zaXRpb24gb2YgTGVmdCBIYW5kLnR4dCIpICU+JQogIGFkZF9yb3coc2VjID0gMjEuNSwgeCA9IDcwMy43NCwgeSA9IDEwNTguMzkpCm1vdXRoIDwtIGdldF94eV90aW1lc3RhbXAoImFvaV9wb3NpdGlvbi9DaW5keV9iZWFyc19GV19Qb3NpdGlvbiBvZiBtb3V0aCBzbWFsbC50eHQiKSAlPiUKICBhZGRfcm93KHNlYyA9IDIxLjUsIHggPSA2NTYuMzcsIHkgPSAzNzMuOTkpCgojIEdldCBTdGVwaGFuaWUncyBkYXRhCnN0ZXBoIDwtIGZpbHRlcihkYXRhLCBuYW1lID09ICJTdGVwaGFuaWUiKQoKc3RlcGggJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2VjcywgeSA9IHkpKSArIAogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEyMDAsMCksIGV4cGFuZCA9IGMoMCwwKSkgKyAKICBnZW9tX2xpbmUoYWxwaGEgPSAxLCBjb2xvciA9ICJwdXJwbGUiKSArIAogICMgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gNy45MiwgeG1heCA9IDguOTIsIHltaW4gPSAwLCB5bWF4ID0gMTIwMCwKICAjIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogICMgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTAuNiwgeG1heCA9IDExLjUyLCB5bWluID0gMCwgeW1heCA9IDEyMDAsCiAgIyBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICAjIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDE0LjA4LCB4bWF4ID0gMTUuMiwgeW1pbiA9IDAsIHltYXggPSAxMjAwLAogICMgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgIyBnZW9tX3N0ZXAoZGF0YSA9IHJoYW5kLCBhZXMoeCA9IHNlYywgeSA9IHkpLCBjb2xvciA9ICJyZWQiLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIsIGFscGhhID0gMC41KSArIAogICMgZ2VvbV9zdGVwKGRhdGEgPSBsaGFuZCwgYWVzKHggPSBzZWMsIHkgPSB5KSwgY29sb3IgPSAiYmx1ZSIsIGxpbmV0eXBlID0gImxvbmdkYXNoIiwgYWxwaGEgPSAwLjUpICsgCiAgIyBnZW9tX3N0ZXAoZGF0YSA9IG1vdXRoLCBhZXMoeCA9IHNlYywgeSA9IHkpLCBjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gImxvbmdkYXNoIiwgYWxwaGEgPSAwLjUpICsgCiAgIyBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIlJpZ2h0IEhhbmQiLCB4ID0gMywgeSA9IDEwMDAsIGNvbG9yID0gInJlZCIsIGFscGhhID0gMC41KSArCiAgIyBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIkxlZnQgSGFuZCIsIHggPSAzLCB5ID0gMTEwMCwgY29sb3IgPSAiYmx1ZSIsIGFscGhhID0gMC41KSArCiAgIyBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIk1vdXRoIiwgeCA9IDMsIHkgPSAyMDAsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjUpICsKICBnZ3RpdGxlKCJTdGVwaGFuaWUiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpKQoKc3RlcGggJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2VjcywgeSA9IHkpKSArIAogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEyMDAsMCksIGV4cGFuZCA9IGMoMCwwKSkgKyAKICBnZW9tX2xpbmUoYWxwaGEgPSAxLCBjb2xvciA9ICJwdXJwbGUiKSArIAogICMgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gNy45MiwgeG1heCA9IDguOTIsIHltaW4gPSAwLCB5bWF4ID0gMTIwMCwKICAjIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogICMgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTAuNiwgeG1heCA9IDExLjUyLCB5bWluID0gMCwgeW1heCA9IDEyMDAsCiAgIyBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICAjIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDE0LjA4LCB4bWF4ID0gMTUuMiwgeW1pbiA9IDAsIHltYXggPSAxMjAwLAogICMgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiMgIGdlb21fc3RlcChkYXRhID0gcmhhbmQsIGFlcyh4ID0gc2VjLCB5ID0geSksIGNvbG9yID0gInJlZCIsIGxpbmV0eXBlID0gImxvbmdkYXNoIiwgYWxwaGEgPSAwLjUpICsgCiMgIGdlb21fc3RlcChkYXRhID0gbGhhbmQsIGFlcyh4ID0gc2VjLCB5ID0geSksIGNvbG9yID0gImJsdWUiLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIsIGFscGhhID0gMC41KSArIAogIGdlb21fc3RlcChkYXRhID0gbW91dGgsIGFlcyh4ID0gc2VjLCB5ID0geSksIGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAibG9uZ2Rhc2giLCBhbHBoYSA9IDAuNSkgKyAKIyBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIlJpZ2h0IEhhbmQiLCB4ID0gMywgeSA9IDEwMDAsIGNvbG9yID0gInJlZCIsIGFscGhhID0gMC41KSArCiMgIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiTGVmdCBIYW5kIiwgeCA9IDMsIHkgPSAxMTAwLCBjb2xvciA9ICJibHVlIiwgYWxwaGEgPSAwLjUpICsKICBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIk1vdXRoIiwgeCA9IDMsIHkgPSAyNTAsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjUpICsKICBnZ3RpdGxlKCJTdGVwaGFuaWUiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpKQoKc3RlcGggJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2VjcywgeSA9IHkpKSArIAogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEyMDAsMCksIGV4cGFuZCA9IGMoMCwwKSkgKyAKICBnZW9tX2xpbmUoYWxwaGEgPSAxLCBjb2xvciA9ICJwdXJwbGUiKSArIAogICMgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gNy45MiwgeG1heCA9IDguOTIsIHltaW4gPSAwLCB5bWF4ID0gMTIwMCwKICAjIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogICMgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTAuNiwgeG1heCA9IDExLjUyLCB5bWluID0gMCwgeW1heCA9IDEyMDAsCiAgIyBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICAjIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDE0LjA4LCB4bWF4ID0gMTUuMiwgeW1pbiA9IDAsIHltYXggPSAxMjAwLAogICMgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgZ2VvbV9zdGVwKGRhdGEgPSByaGFuZCwgYWVzKHggPSBzZWMsIHkgPSB5KSwgY29sb3IgPSAicmVkIiwgbGluZXR5cGUgPSAibG9uZ2Rhc2giLCBhbHBoYSA9IDAuNSkgKyAKIyAgZ2VvbV9zdGVwKGRhdGEgPSBsaGFuZCwgYWVzKHggPSBzZWMsIHkgPSB5KSwgY29sb3IgPSAiYmx1ZSIsIGxpbmV0eXBlID0gImxvbmdkYXNoIiwgYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9zdGVwKGRhdGEgPSBtb3V0aCwgYWVzKHggPSBzZWMsIHkgPSB5KSwgY29sb3IgPSAiYmxhY2siLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIsIGFscGhhID0gMC41KSArIAogIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiUmlnaHQgSGFuZCIsIHggPSAzLCB5ID0gMTAwMCwgY29sb3IgPSAicmVkIiwgYWxwaGEgPSAwLjUpICsKIyAgYW5ub3RhdGUoInRleHQiLCBsYWJlbCA9ICJMZWZ0IEhhbmQiLCB4ID0gMywgeSA9IDExMDAsIGNvbG9yID0gImJsdWUiLCBhbHBoYSA9IDAuNSkgKwogIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiTW91dGgiLCB4ID0gMywgeSA9IDI1MCwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNSkgKwogIGdndGl0bGUoIlN0ZXBoYW5pZSIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgpzdGVwaCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBzZWNzLCB5ID0geSkpICsgCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSwgZXhwYW5kID0gYygwLDApKSArIAogIGdlb21fbGluZShhbHBoYSA9IDEsIGNvbG9yID0gInB1cnBsZSIpICsgCiAgIyBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSA3LjkyLCB4bWF4ID0gOC45MiwgeW1pbiA9IDAsIHltYXggPSAxMjAwLAogICMgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgIyBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxMC42LCB4bWF4ID0gMTEuNTIsIHltaW4gPSAwLCB5bWF4ID0gMTIwMCwKICAjIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogICMgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTQuMDgsIHhtYXggPSAxNS4yLCB5bWluID0gMCwgeW1heCA9IDEyMDAsCiAgIyBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBnZW9tX3N0ZXAoZGF0YSA9IHJoYW5kLCBhZXMoeCA9IHNlYywgeSA9IHkpLCBjb2xvciA9ICJyZWQiLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIsIGFscGhhID0gMC41KSArIAogIGdlb21fc3RlcChkYXRhID0gbGhhbmQsIGFlcyh4ID0gc2VjLCB5ID0geSksIGNvbG9yID0gImJsdWUiLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIsIGFscGhhID0gMC41KSArIAogIGdlb21fc3RlcChkYXRhID0gbW91dGgsIGFlcyh4ID0gc2VjLCB5ID0geSksIGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAibG9uZ2Rhc2giLCBhbHBoYSA9IDAuNSkgKyAKICBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIlJpZ2h0IEhhbmQiLCB4ID0gMywgeSA9IDEwMDAsIGNvbG9yID0gInJlZCIsIGFscGhhID0gMC41KSArCiAgYW5ub3RhdGUoInRleHQiLCBsYWJlbCA9ICJMZWZ0IEhhbmQiLCB4ID0gMywgeSA9IDExMDAsIGNvbG9yID0gImJsdWUiLCBhbHBoYSA9IDAuNSkgKwogIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiTW91dGgiLCB4ID0gMywgeSA9IDI1MCwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNSkgKwogIGdndGl0bGUoIlN0ZXBoYW5pZSIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKTm93IGxldCdzIHdvcmsgb24gY29ycmVsYXRpb25zLiBGaXJzdCwgb3VyIEFPSSB2ZWN0b3JzIGFyZSBub3QgdGhlIHNhbWUgc2l6ZSBhcyBvdXIgZXllIGdhemUgdmVjdG9ycywgYW5kIHRoZSB4L3kgcG9zaXRpb24gaXMgaXJyZWd1bGFybHkgc3BhY2VkIGFjcm9zcyB0aW1lIChpcnJlZ3VsYXJseSBzcGFjZWQga2V5IGZyYW1lcykuIApgYGB7cn0KIyBUaGUgZm9sbG93aW5nIGNvZGUgd2lsbCAiZXhwYW5kIiB0aGUgcmhhbmQgZGF0YSB2ZWN0b3JzIHRvIGZpdCB0aGUgbGVuZ3RoIG9mIFN0ZXBoYW5pZSdzIGRhdGEgdmVjdG9ycy4KdGltZV9pbmRleCA8LSBzdGVwaCRzZWNzCmNsb3Nlc3QgPC0gZnVuY3Rpb24oeCl7CiAgd2hpY2gubWluKGFicyh0aW1lX2luZGV4LXgpKQp9CgppbmRleF9sb2MgPC0gbWFwX2ludChyaGFuZCRzZWMsIGNsb3Nlc3QpCgpyaGFuZCA8LSBjYmluZChyaGFuZCwgdGltZV9pbmRleFtpbmRleF9sb2NdKSAlPiUKICBzZWxlY3QoLXNlYykgJT4lCiAgcmVuYW1lKHNlYyA9ICJ0aW1lX2luZGV4W2luZGV4X2xvY10iKSAlPiUKICBzZWxlY3Qoc2VjLCB4LCB5KQoKcmhhbmRfZnVsbCA8LSBzZWxlY3Qoc3RlcGgsIHNlY3MpICU+JQogIHJlbmFtZShzZWMgPSBzZWNzKSAlPiUKICBsZWZ0X2pvaW4ocmhhbmQpICU+JQogIGZpbGwoeCkgJT4lCiAgZmlsbCh5KSAlPiUKICBzbGljZSgxOihucm93KC4pLTEpKQoKcmhhbmRfZnVsbCA8LSByaGFuZF9mdWxsICU+JQogIGZpbHRlcihzZWMgPCByaGFuZCRzZWNbMTcyXSkgJT4lCiAgZmlsdGVyKHNlYyA+PSByaGFuZCRzZWNbMl0pCgpzdGVwaCA8LSBzdGVwaCAlPiUKICBmaWx0ZXIoc2VjcyA8IHJoYW5kJHNlY1sxNzJdKSAlPiUKICBmaWx0ZXIoc2VjcyA+PSByaGFuZCRzZWNbMl0pCgphIDwtIHJoYW5kX2Z1bGwkeQphIDwtIGFbMTpsZW5ndGgoYSktMV0gIyBTaG9ydGVuIGl0IGJ5IG9uZSBlbGVtZW50CmIgPC0gc3RlcGgkeQoKIyBUaGVuIHJ1biBjb3JyZWxhdGlvbnMKY29yKGEsYiwgdXNlID0gImNvbXBsZXRlLm9icyIpICMgYmFzaWMgY29ycmVsYXRpb24KdGhhdCA8LSBjY2YoYSxiLCBsYWcubWF4ID0gNDAwLCB0eXBlID0gImNvcnJlbGF0aW9uIiwgbmEuYWN0aW9uID0gbmEucGFzcywgcGxvdCA9IFQpICMgYXV0by1jb3JyZWxhdGlvbgpgYGAKCgpMZXQncyBzZXBhcmF0ZSBvdXQgaW5kaXZpZHVhbCBzaWduZXJzLiAKCmBgYHtyfQptYWtlX3NpZ25lcl9wbG90cyA8LSBmdW5jdGlvbihncm91cG5hbWUsIGxpbmVfY29sb3IpIHsKICBkYXRhICU+JQogIGZpbHRlcihtYWluZ3JvdXAgPT0gZ3JvdXBuYW1lKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBzZWNzLCB5ID0geSkpICsgCiAgc2NhbGVfeV9yZXZlcnNlKCkgKyAKICBnZW9tX2xpbmUoYWxwaGEgPSAxLCBjb2xvciA9IGxpbmVfY29sb3IpICsgCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gNy45MiwgeG1heCA9IDguOTIsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDEwLjYsIHhtYXggPSAxMS41MiwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTQuMDgsIHhtYXggPSAxNS4yLCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBnZW9tX3N0ZXAoZGF0YSA9IHJoYW5kLCBhZXMoeCA9IHNlYywgeSA9IHkpLCBjb2xvciA9ICJyZWQiLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIsIGFscGhhID0gMC41KSArIAogIGdlb21fc3RlcChkYXRhID0gbGhhbmQsIGFlcyh4ID0gc2VjLCB5ID0geSksIGNvbG9yID0gImJsdWUiLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIsIGFscGhhID0gMC41KSArIAogIGdlb21fc3RlcChkYXRhID0gbW91dGgsIGFlcyh4ID0gc2VjLCB5ID0geSksIGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAibG9uZ2Rhc2giLCBhbHBoYSA9IDAuNSkgKyAKICBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIlJpZ2h0IEhhbmQiLCB4ID0gMywgeSA9IDEwMDAsIGNvbG9yID0gInJlZCIsIGFscGhhID0gMC41KSArCiAgYW5ub3RhdGUoInRleHQiLCBsYWJlbCA9ICJMZWZ0IEhhbmQiLCB4ID0gMywgeSA9IDExMDAsIGNvbG9yID0gImJsdWUiLCBhbHBoYSA9IDAuNSkgKwogIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiTW91dGgiLCB4ID0gMywgeSA9IDIwMCwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNSkgKwogIGZhY2V0X2dyaWQobmFtZSB+IC4pICsKICBnZ3RpdGxlKGdyb3VwbmFtZSkgKwogIHRoZW1lX2J3KCkKfQoKbWFrZV9zaWduZXJfcGxvdHMoIkRlYWZFYXJseSIsICJyZWQiKQptYWtlX3NpZ25lcl9wbG90cygiRGVhZkxhdGUiLCAiZGFyayBncmVlbiIpCm1ha2Vfc2lnbmVyX3Bsb3RzKCJIZWFyaW5nTGF0ZSIsICJibHVlIikKbWFrZV9zaWduZXJfcGxvdHMoIkhlYXJpbmdOb3ZpY2UiLCAicHVycGxlIikKYGBgCgpPa2F5IHNvIHdpdGggRWFybHkgQVNMIG9idmlvdXNseSB2ZXJ5IHN0ZWFkeSBnYXplLiBOb3ZpY2VBU0wgaGFzIGxvdCBvZiBkb3duc2hpZnRzLiBTb21lIGFsaWduIHdpdGggc3BhdGlhbCByZWZlcmVuY2luZywgc29tZSBkbyBub3QuIFdlIG5lZWQgbW9yZSBvZiB0aGVtIChsZXQncyBsb29rIGF0IG90aGVyIHN0b3JpZXMgdyBiZXR0ZXIgZGF0YSkuIAoKCiMgTWlkYXMgRm9yd2FyZAoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBHZXQgTWlkYXMgZGF0YQpkYXRhIDwtIHJlYWRfY3N2KCIuLi9BZHVsdCBEYXRhL3Jhd2RhdGEvbWlkYXNmdy5jc3YiKSAlPiUKICBjbGVhbl9uYW1lcygpICU+JQogIHJlbmFtZSh5ID0gZ2F6ZV9wb2ludF95X21jX3NweCwKICAgICAgICAgbGFuZ3VhZ2UgPSBsYW5ndWFnZV92YWx1ZSwKICAgICAgICAgbmFtZSA9IHBhcnRpY2lwYW50X25hbWUsCiAgICAgICAgIGdyb3VwID0gZ3JvdXBfdmFsdWUpCgojIFB1bGwgY2xlYW4gbmFtZXMgYW5kIGpvaW4gdG8gZGF0YQpjbGVhbm5hbWVzIDwtIHJlYWRfY3N2KCJwYXJ0bmFtZXMuY3N2IikgJT4lCiAgZGlzdGluY3QoKSAlPiUKICByZW5hbWUobmFtZSA9IHBhcnRpY2lwYW50KQoKZGF0YSA8LSBkYXRhICU+JSBsZWZ0X2pvaW4oY2xlYW5uYW1lcywgYnkgPSAibmFtZSIpICU+JQogIHNlbGVjdCgtbmFtZSkgJT4lCiAgcmVuYW1lKG5hbWUgPSBuZXdfcGFydGljaXBhbnQpICU+JQogIGZpbHRlcighaXMubmEobmFtZSkpCgojIFB1bGwgZmluYWwgZ3JvdXAgYXNzaWdubWVudHMgYW5kIGpvaW4gdG8gZGF0YQpjbGVhbmdyb3VwcyA8LSByZWFkX2NzdigiZmluYWxkYXRhc2V0LmNzdiIpICU+JQogIHNlbGVjdChwYXJ0aWNpcGFudCwgbWFpbmdyb3VwKSAlPiUKICByZW5hbWUobmFtZSA9IHBhcnRpY2lwYW50KSAlPiUKICBkaXN0aW5jdCgpCgpkYXRhIDwtIGRhdGEgJT4lIGxlZnRfam9pbihjbGVhbmdyb3VwcywgYnkgPSAibmFtZSIpICU+JQogIHNlbGVjdCgtZ3JvdXApCgojIExldCdzIGZpbmQgb3V0IHdobyB3YXMgTk9UIGluY2x1ZGVkIGluIFRocmVlIEJlYXJzCmV4Y2x1ZGVkIDwtIHJlYWRfY3N2KCJmaW5hbGRhdGFzZXQuY3N2IikgJT4lCiAgc2VsZWN0KHBhcnRpY2lwYW50LCBtYWluZ3JvdXAsIHN0b3J5LCBkaXJlY3Rpb24sIGV5ZV9leGNsdWRlKSAlPiUKICBmaWx0ZXIoc3RvcnkgPT0gIktpbmdNaWRhcyIgJiBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSAlPiUKICByZW5hbWUobmFtZSA9IHBhcnRpY2lwYW50KSAlPiUKICBzZWxlY3QobmFtZSwgZXllX2V4Y2x1ZGUpCgpkYXRhIDwtIGRhdGEgJT4lIGxlZnRfam9pbihleGNsdWRlZCwgYnkgPSAibmFtZSIpICU+JQogIGZpbHRlcighZXllX2V4Y2x1ZGUpICU+JQogIGZpbHRlcighaXMubmEoZXllX2V4Y2x1ZGUpKQoKZGF0YSAlPiUgc2VsZWN0KG5hbWUsIG1haW5ncm91cCkgJT4lIGRpc3RpbmN0KCkKYGBgCgpOb3cgbGV0J3MgZ3JhcGghISAKCkhtLiBPbmUgcGVyc29uIHNlZW1zIHdyb25nLiAKYGBge3J9CmRhdGEgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgeSA9IHksIGNvbG9yID0gbWFpbmdyb3VwLCBncm91cCA9IG5hbWUpKSArIGdlb21fbGluZSgpICsgc2NhbGVfeV9yZXZlcnNlKCkKYGBgCk9rYXkgaXQncyBKZXNzZSdzIGRhdGEgdGhhdCBzZWVtcyBvZmYuIFdlJ2xsIHJlbW92ZSBoaW0gZm9yIG5vdyBhbmQgY29tZSBiYWNrIHRvIGl0LCBmaWd1cmUgb3V0IHdoeS4gCmBgYHtyfQpkYXRhICU+JSBmaWx0ZXIoZ2F6ZV9wb2ludF9pbmRleCA+IDMwMDAwKSAlPiUgc2VsZWN0KG5hbWUpICU+JSBkaXN0aW5jdCgpICU+JSBoZWFkKCkKYGBgCgpgYGB7cn0KZGF0YSA8LSBkYXRhICU+JQogIGZpbHRlcihuYW1lICE9ICJKZXNzZSIpCgpkYXRhICU+JQogIGdncGxvdChhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIHkgPSB5LCBjb2xvciA9IG1haW5ncm91cCwgZ3JvdXAgPSBuYW1lKSkgKyBnZW9tX2xpbmUoKSArIAogIHNjYWxlX3lfcmV2ZXJzZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDQ1MDApKQpgYGAKCk5leHQgbGV0J3MgcGxvdCB0aGUgbW9tZW50cyB3aGVyZSBzcGF0aWFsIHJlZmVyZW5jaW5nIGhhcHBlbnMuIFRob3NlIGFyZSBmcmFtZXMKCjEuIDI0OCB0byA0MjcKMS4gNDYwIHRvIDUwOAoxLiA1MTIgdG8gNTYwCgpMaWtlIGJlZm9yZSwgd2UnbGwgY29udmVydCBnYXplcG9pbnRpbmRleCB0byBzZWNvbmRzIChieSBkaXZpZGluZyAxMjApIGFuZCBhbGwgZnJhbWVzIHRvIHNlY29uZHMgKGJ5IGRpdmlkaW5nIDI1KS4gCgoxLiA5LjkycyB0byAxNy4wOHMKMS4gMTguNHMgdG8gMjAuMzJzCjEuIDIwLjQ4cyB0byAyMi40cyAKCmBgYHtyfQpkYXRhIDwtIGRhdGEgJT4lCiAgcm93d2lzZSgpICU+JQogIG11dGF0ZShzZWNzID0gZ2F6ZV9wb2ludF9pbmRleC8xMjApCgpkYXRhICU+JQogIGdncGxvdChhZXMoeCA9IHNlY3MsIHkgPSB5LCBjb2xvciA9IG1haW5ncm91cCwgZ3JvdXAgPSBuYW1lKSkgKyAKICBzY2FsZV95X3JldmVyc2UoKSArIAogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDM3LjUpKSArCiAgZ2VvbV9saW5lKCkgKyAKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSA5LjkyLCB4bWF4ID0gMTcuMDgsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDE4LjQsIHhtYXggPSAyMC4zMiwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMjAuNDgsIHhtYXggPSAyMi40LCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpCmBgYAoKTWF5YmUgZWFzaWVyIGlmIHdlIHNlcGFyYXRlIGdyb3VwcyBvZiBzaWduZXJzLiAKCmBgYHtyfQpkYXRhICU+JQogIGdncGxvdChhZXMoeCA9IHNlY3MsIHkgPSB5LCBjb2xvciA9IG1haW5ncm91cCwgZ3JvdXAgPSBuYW1lKSkgKyAKICBzY2FsZV95X3JldmVyc2UoKSArIAogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDM3LjUpKSArCiAgZ2VvbV9saW5lKGFscGhhID0gMC41KSArIAogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDkuOTIsIHhtYXggPSAxNy4wOCwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTguNCwgeG1heCA9IDIwLjMyLCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAyMC40OCwgeG1heCA9IDIyLjQsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGZhY2V0X2dyaWQobWFpbmdyb3VwIH4gLikKYGBgCgpJbmRpdmlkdWFsIHNpZ25lcnMuIAoKYGBge3J9CmRhdGEgJT4lCiAgZmlsdGVyKG1haW5ncm91cCA9PSAiRGVhZkVhcmx5IikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2VjcywgeSA9IHksIGdyb3VwID0gbmFtZSkpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMzcuNSkpICsKICBzY2FsZV95X3JldmVyc2UoKSArIAogIGdlb21fbGluZShhbHBoYSA9IDEsIGNvbG9yID0gInJlZCIpICsgCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gOS45MiwgeG1heCA9IDE3LjA4LCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxOC40LCB4bWF4ID0gMjAuMzIsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDIwLjQ4LCB4bWF4ID0gMjIuNCwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgZmFjZXRfZ3JpZChuYW1lIH4gLikgKwogIGdndGl0bGUoIkRlYWZFYXJseSIpCgpkYXRhICU+JQogIGZpbHRlcihtYWluZ3JvdXAgPT0gIkRlYWZMYXRlIikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2VjcywgeSA9IHksIGdyb3VwID0gbmFtZSkpICsgCiAgc2NhbGVfeV9yZXZlcnNlKCkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAzNy41KSkgKwogIGdlb21fbGluZShhbHBoYSA9IDEsIGNvbG9yID0gImRhcmsgZ3JlZW4iKSArIAogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDkuOTIsIHhtYXggPSAxNy4wOCwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTguNCwgeG1heCA9IDIwLjMyLCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAyMC40OCwgeG1heCA9IDIyLjQsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGZhY2V0X2dyaWQobmFtZSB+IC4pICsKICBnZ3RpdGxlKCJEZWFmTGF0ZSIpCgpkYXRhICU+JQogIGZpbHRlcihtYWluZ3JvdXAgPT0gIkhlYXJpbmdMYXRlIikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2VjcywgeSA9IHksIGdyb3VwID0gbmFtZSkpICsgCiAgc2NhbGVfeV9yZXZlcnNlKCkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAzNy41KSkgKwogIGdlb21fbGluZShhbHBoYSA9IDEsIGNvbG9yID0gImJsdWUiKSArIAogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDkuOTIsIHhtYXggPSAxNy4wOCwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTguNCwgeG1heCA9IDIwLjMyLCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAyMC40OCwgeG1heCA9IDIyLjQsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGZhY2V0X2dyaWQobmFtZSB+IC4pICsKICBnZ3RpdGxlKCJIZWFyaW5nTGF0ZSIpCgpkYXRhICU+JQogIGZpbHRlcihtYWluZ3JvdXAgPT0gIkhlYXJpbmdOb3ZpY2UiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBzZWNzLCB5ID0geSwgZ3JvdXAgPSBuYW1lKSkgKyAKICBzY2FsZV95X3JldmVyc2UoKSArIAogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDM3LjUpKSArCiAgZ2VvbV9saW5lKGFscGhhID0gMSwgY29sb3IgPSAicHVycGxlIikgKyAKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSA5LjkyLCB4bWF4ID0gMTcuMDgsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDE4LjQsIHhtYXggPSAyMC4zMiwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMjAuNDgsIHhtYXggPSAyMi40LCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBmYWNldF9ncmlkKG5hbWUgfiAuKSArCiAgZ2d0aXRsZSgiSGVhcmluZ05vdmljZSIpCmBgYA==